using MediatR;
using Microsoft.Extensions.Logging;
using RBAC.Domain.Approval;
using RBAC.ErrorCode;
using RBAC.Interstructrue.Base;
using RBAC.Read.Api.Application.Command.Approval;
using RBAC.Read.Api.Application.Dto.Approval;

namespace RBAC.Read.Api.Application.Handler.Approval
{
    /// <summary>
    /// 获取审批流程详情（含节点）处理器
    /// </summary>
    public class GetApprovalProcessDetailHandler : IRequestHandler<GetApprovalProcessDetailCommand, APIResult<ApprovalProcessDetailDto>>
    {
        private readonly IBaseRepository<ApprovalProcess> approvalProcessRepository;
        private readonly IBaseRepository<ApprovalNode> approvalNodeRepository;
        private readonly ILogger<GetApprovalProcessDetailHandler> logger;

        public GetApprovalProcessDetailHandler(
            IBaseRepository<ApprovalProcess> approvalProcessRepository,
            IBaseRepository<ApprovalNode> approvalNodeRepository,
            ILogger<GetApprovalProcessDetailHandler> logger)
        {
            this.approvalProcessRepository = approvalProcessRepository;
            this.approvalNodeRepository = approvalNodeRepository;
            this.logger = logger;
        }

        public Task<APIResult<ApprovalProcessDetailDto>> Handle(GetApprovalProcessDetailCommand request, CancellationToken cancellationToken)
        {
            var result = new APIResult<ApprovalProcessDetailDto>();
            try
            {
                cancellationToken.ThrowIfCancellationRequested();
                if (request.Id <= 0)
                {
                    result.Code = APIEnums.Error;
                    result.Msg = "参数无效：Id";
                    return Task.FromResult(result);
                }

                var process = approvalProcessRepository.GetModel(request.Id);
                if (process == null || process.IsDeleted)
                {
                    result.Code = APIEnums.Error;
                    result.Msg = "审批流程不存在";
                    return Task.FromResult(result);
                }

                var dto = new ApprovalProcessDetailDto
                {
                    Id = process.Id,
                    ProcessName = process.ProcessName,
                    Description = process.Description,
                    ProcessType = process.ProcessType,
                    BusinessType = GetBusinessTypeFromProcessType(process.ProcessType),
                    Status = process.Status,
                    IsEnabled = process.Status == 1,
                };

                // 查询节点，按照 NodeOrder 排序
                var nodeSql = "SELECT NodeName, ApproverId, ApproverName, ApprovalType, NodeOrder FROM ApprovalNode WHERE IsDeleted=0 AND ProcessId=@ProcessId ORDER BY NodeOrder ASC";
                var nodes = approvalNodeRepository.Query<ApprovalNode>(nodeSql, new { ProcessId = process.Id })
                    .Select(n => new ApprovalNodeDto
                    {
                        NodeName = n.NodeName ?? string.Empty,
                        ApproverId = n.ApproverId,
                        ApproverName = n.ApproverName ?? string.Empty,
                        ApprovalType = n.ApprovalType,
                        NodeOrder = n.NodeOrder
                    }).ToList();
                dto.Nodes = nodes;

                result.Code = APIEnums.Success;
                result.Msg = "获取成功";
                result.Data = dto;
            }
            catch (OperationCanceledException)
            {
                result.Code = APIEnums.Error;
                result.Msg = "请求已取消";
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "获取审批流程详情失败: {Message}", ex.Message);
                result.Code = APIEnums.Error;
                result.Msg = "获取审批流程详情失败";
            }

            return Task.FromResult(result);
        }

        private static int GetBusinessTypeFromProcessType(string processType)
        {
            return processType switch
            {
                "采购订单" => 1,
                "销售订单" => 2,
                "入库单" => 3,
                "出库单" => 4,
                _ => 0
            };
        }
    }
}
